Frontend Forever App
We have a mobile app for you to download and use. And you can unlock many features in the app.
Get it now
Intall Later
Run
HTML
CSS
Javascript
Output
Document
//- Cherry Tree (Animated) Grant Jenkins, August 2024 #cpc-wild-fractals, #codepenchallenge Just playing around with some recursion :) Click the screen to generate a new tree See my other programs/games/animations, etc. on Khan Academy https://www.khanacademy.org/profile/grantjenkins/projects canvas#canvas script(src="https://cdn.jsdelivr.net/processing.js/1.4.8/processing.min.js")
@charset "UTF-8"; @import url(https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,600,700,800); *, :after, :before { box-sizing: border-box; padding: 0; margin: 0; } * { margin: 0; box-sizing: border-box; overflow: hidden; } body { background: rgb(230, 226, 202); width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; canvas { box-shadow: 0.2em 0.2em 2em #0008; border: none; outline: none; } }
console.log("Event Fired") var sketchProc = function(processingInstance) { with (processingInstance) { size(600, 600); frameRate(60); smooth(); textAlign(CENTER, CENTER); textSize(25); strokeCap(PROJECT); //used for controlling the animation var lenBranches = 0, lenLeaves = 0, lenFlowers = 0; //define the tree object/properties var tree = { x: 300, y: 500, len: 100, depth: 6, angle: -90, branches: [], leaves: [], flowers: [], colors: { from: color(59, 39, 8), to: color(145, 108, 49) } }; //the recursive function (will be called from within itself) var addBranch = function(x, y, depth, angle, len) { //if the depth is zero then end the recursion if(depth === 0) { return; } //calculate the end points of the branch var x2 = x + cos(angle*Math.PI/180) * len; var y2 = y + sin(angle*Math.PI/180) * len; //add the new branch to the tree tree.branches.push({ x1: x, y1: y, x2: x2, y2: y2, depth: depth, color: lerpColor(tree.colors.from, tree.colors.to, map(depth, tree.depth, 1, 0, 1)) }); //add some random leaves to the branches if(depth > 0 && depth < tree.depth - 3 && random() < 0.3) { for(var i = 0; i < 2; i++) { var l = len * random(0.1, 0.9); var tx = x + cos(angle*Math.PI/180) * l; var ty = y + sin(angle*Math.PI/180) * l; tree.leaves.push({ x: tx, y: ty, diameter: random(5, 10), color: color(random(80, 100), random(150, 180), random(90, 110)), angle: random(angle - 60, angle + 60) }); } } //add some random flowers to the end of the branches if(depth === 1 && random() < 0.5 || depth === 2 && random() < 0.3) { tree.flowers.push({ x: x2, y: y2, diameter: depth === 1 ? random(15, 25) : random(10, 15), color: color(random(200, 255), random(60, 100), random(90, 120)), angle: angle, gap: random(0, 90) }); } //reduce the depth (extremely important to end your recursion) depth--; var l = len * (random(0.6, 0.8)); var x3 = x + cos(angle*Math.PI/180) * l; var y3 = y + sin(angle*Math.PI/180) * l; //call this function recursively addBranch(x2, y2, depth, angle - random(10, 50), len * random(0.75, 0.85)); addBranch(x2, y2, depth, angle + random(10, 50), len * random(0.75, 0.85)); addBranch(x3, y3, depth, angle + random(-30, 30), len * random(0.75, 0.85)); }; //call the recusive function addBranch(tree.x, tree.y, tree.depth, tree.angle, tree.len); draw = function() { background(230, 226, 202); noStroke(); fill(50, 30); ellipse(tree.x, tree.y + 5, 200, 35); //draw the trees for(var i = 0; i < lenBranches; i++) { var branch = tree.branches[i]; //set the stroke opacity based on the branch depth stroke(branch.color, 50 + branch.depth * 35); //set the stroke thickness based on the branch depth strokeWeight(1 + branch.depth); //draw the branch line(branch.x1, branch.y1, branch.x2, branch.y2); } //used for animating the branches lenBranches = constrain(lenBranches + 1, 0, tree.branches.length); //if all the branches are displayed then show the leaves if(lenBranches === tree.branches.length) { //draw the leaves for(var i = 0; i < lenLeaves; i++) { var leaf = tree.leaves[i]; pushStyle(); noStroke(); fill(leaf.color); arc(leaf.x, leaf.y, leaf.diameter, leaf.diameter, (leaf.angle + 70)*Math.PI/180, (leaf.angle + 290)*Math.PI/180); popStyle(); } //used for animating the leaves lenLeaves = constrain(lenLeaves + 1, 0, tree.leaves.length); } //if all the leaves are displayed then show the flowers if(lenLeaves === tree.leaves.length) { //draw the flowers for(var i = 0; i < lenFlowers; i++) { var flower = tree.flowers[i]; pushStyle(); noStroke(); fill(flower.color); arc(flower.x, flower.y, flower.diameter, flower.diameter, (flower.angle + flower.gap)*Math.PI/180, (flower.angle + 360 - flower.gap)*Math.PI/180); popStyle(); } if(++lenFlowers === tree.flowers.length + 1) { noLoop(); } } //display how many branches there are fill(50, 50); text(tree.branches.length + " branches, " + tree.leaves.length + " leaves, " + tree.flowers.length + " flowers", 300, 30); text("click to generate a new tree", 300, 570); }; mouseClicked = function() { tree.branches.length = 0; tree.leaves.length = 0; tree.flowers.length = 0; lenBranches = 0; lenLeaves = 0; lenFlowers = 0; tree.angle = random(-100, -80); addBranch(tree.x, tree.y, tree.depth, tree.angle, tree.len); loop(); }; } } var canvas = document.getElementById("canvas"); var processingInstance = new Processing(canvas, sketchProc);